#!/usr/bin/perl
use strict;
use warnings;
use Perl::Build;
use Devel::PatchPerl;
use Getopt::Long;
use Pod::Usage;
use File::Spec;

my $test = undef;
my $patches;
my $build_dir;
my $symlink_devel_executables;
my (@D, @A, @U);
Getopt::Long::Configure(
    'pass_through',
    'no_ignore_case',
    'bundling',
);
GetOptions(
    'h|help' => \my $help,
    'test!' => \$test,
    'D=s@'  => \@D,
    'A=s@'  => \@A,
    'U=s@'  => \@U,
    'definitions' => \my $definitions,
    'patches=s' => \$patches,
    'build-dir=s' => \$build_dir,
    'j|jobs=i' => \my $jobs,
    'tarball-dir=s' => \my $tarball_dir,
    'version' => \my $show_version,
    'symlink-devel-executables!' => \$symlink_devel_executables,
    'noman' => \my $noman,
);
for (@D, @A, @U) {
    s/^=//;
}

if ($show_version) {
    print "perl-build $Perl::Build::VERSION ($0)\n";
    print "perl $] ($^X)\n";
    print "Devel::PatchPerl $Devel::PatchPerl::VERSION\n";
    exit 0;
}

pod2usage(1) if $help;

if ($definitions) {
    for (Perl::Build->available_perls()) {
        print "$_\n";
    }
    exit 0;
}

shift @ARGV if @ARGV >= 1 && $ARGV[0] eq '--';

my $stuff   = shift @ARGV or pod2usage();
my $dest    = shift @ARGV or pod2usage();
   $dest    = File::Spec->rel2abs($dest);

my @configure_options = @ARGV ? @ARGV : ('-de');
push @configure_options, map { "-D$_" } @D;
push @configure_options, map { "-A$_" } @A;
push @configure_options, map { "-U$_" } @U;
push @configure_options, "-Dman1dir=none", "-Dman3dir=none" if $noman;

$ENV{PERL5_PATCHPERL_PLUGIN} = $patches if defined $patches;

if ($stuff eq 'blead') {
    my $url = "https://github.com/Perl/perl5/archive/blead.tar.gz";
    Perl::Build->install_from_url(
        $url => (
            dst_path          => $dest,
            configure_options => ['-Dusedevel', @configure_options],
            test              => $test,
            build_dir         => $build_dir,
            jobs              => $jobs,
            tarball_dir       => $tarball_dir,
        )
    );
} elsif ($stuff =~ m{^https?://}) {
    Perl::Build->install_from_url(
        $stuff => (
            dst_path          => $dest,
            configure_options => \@configure_options,
            test              => $test,
            build_dir         => $build_dir,
            jobs              => $jobs,
            tarball_dir       => $tarball_dir,
        )
    );
} elsif ($stuff =~ /\.(gz|bz2|xz)$/) {
    Perl::Build->install_from_tarball(
        $stuff => (
            dst_path          => $dest,
            configure_options => \@configure_options,
            test              => $test,
            build_dir         => $build_dir,
            jobs              => $jobs,
        )
    );
} else {
    my $version = $stuff;
    Perl::Build->install_from_cpan(
        $version => (
            dst_path          => $dest,
            configure_options => \@configure_options,
            test              => $test,
            build_dir         => $build_dir,
            jobs              => $jobs,
            tarball_dir       => $tarball_dir,
        )
    );
}

if ($symlink_devel_executables) {
    Perl::Build->symlink_devel_executables(
        File::Spec->catdir($dest, 'bin')
    );
}

__END__

=head1 NAME

perl-build - perl binary builder

=head1 SYNOPSIS 

    # perl-build command is FatPacker ready
    % curl -L https://raw.github.com/tokuhirom/Perl-Build/master/perl-build | perl - 5.16.2 /opt/perl-5.16/

    # Or, just install from CPAN
    % cpanm Perl::Build

    # And run it.
    % perl-build 5.16.2 /usr/local/perl-5.16.2
    % perl-build path/to/perl-5.16.2.tar.gz /usr/local/perl-5.16.2

=head1 DESCRIPTION

This script fetch/build/install perl5 from CPAN or tar ball.

=head1 OPTIONS

=over 4

=item -D, -A, -U

-Dxxx, -Axxx, -Uxxx options are pass through to ./Configure script.

=item --test

This option enables C<< make test >> after building.

(Default: disabled)

=item --patches=Asan

You can set I<PERL5_PATCHPERL_PLUGIN> environment variable by this option.

=item --build-dir=path

Specify perl build path. optional. (Default: temporary directory)

=item -j n

=item --jobs n

Parallel building and testing.

=item --tarball-dir

Specify the tar ball saving directory.

(Default: temporary directory, will remove after building)

=item --definitions

    % perl-build --definitions

Display the available perl versions and exit.

=item --version

Show version number and exit.

=item --symlink-devel-executables

Create symlinks for development version perl commands.

=item --noman

Skip installation of manpages.
This is equivalent to specifying C<-Dman1dir=none> and C<-Dman3dir=none>.

=back

=head1 FAQ

=over 4

=item How can I apply security fixes like CVE-2013-1667?

RURBAN provides L<Devel::PatchPerl::Plugin::Asan>. Install it and run C<< perl-build --patches=Asan 5.16.1 /opt/perl/5.16/ >>.

=back

=head1 SEE ALSO

L<perlbrew>, L<plenv>

